<template>
  <div class="task-container">
    <!-- 主要内容区域 - 合并搜索和列表 -->
    <el-card class="form-card task-list-card" shadow="hover">
      <template #header>
        <!-- 搜索区域 -->
        <div class="search-container">
          <div class="search-row">
            <div class="search-item">
              <span class="label">测试用例状态</span>
              <el-select
                v-model="status"
                placeholder="全部"
                class="input-width"
              >
                <el-option label="全部" value=""></el-option>
                <el-option label="已分配" value="已分配"></el-option>
                <el-option label="已推送" value="已推送"></el-option>
              </el-select>
            </div>
            <div class="search-item">
              <span class="label">需求书名称</span>
              <el-input
                v-model="name"
                placeholder="请输入需求书名称"
                class="input-width"
              ></el-input>
            </div>
            <div class="search-item">
              <span class="label">测试用例编号</span>
              <el-input
                v-model="code"
                placeholder="请输入测试用例编号"
                class="input-width"
              ></el-input>
            </div>
            <div class="buttons">
              <el-button type="primary" @click="handleSearch" :icon="Search"
                >查询</el-button
              >
              <el-button @click="resetSearch" :icon="RefreshRight"
                >重置</el-button
              >
            </div>
          </div>
        </div>
      </template>

      <div class="card-header">
        <div class="left-actions">
          <el-button
            type="primary"
            @click="openUploadDialog"
            class="add-task-btn"
            :icon="Plus"
          >
            创建任务
          </el-button>
        </div>
        <div class="right-actions">
          <el-button class="action-btn" :icon="Download"> 导出Excel </el-button>
          <el-button
            :disabled="multipleSelection.length === 0"
            @click="handleBatchAction"
            class="action-btn"
            :icon="Connection"
          >
            推送禅道
          </el-button>
        </div>
      </div>

      <!-- 表格区域 -->
      <el-table
        :data="tableData"
        border
        @selection-change="handleSelectionChange"
        class="task-table"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column type="expand">
          <template #default="props">
            <TaskDetail :task="props.row" />
          </template>
        </el-table-column>
        <el-table-column
          prop="code"
          label="测试用例编号"
          width="150"
          sortable
        ></el-table-column>
        <el-table-column
          prop="name"
          label="需求书名称"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag
              :type="scope.row.status === '已推送' ? 'success' : 'info'"
              size="small"
            >
              {{ scope.row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="测试用例数量" width="220">
          <template #default="scope">
            <div
              v-if="scope.row && scope.row.testCaseList"
              class="demand-info-cell"
            >
              <div class="info-item">
                <el-tag size="small" type="success">{{
                  scope.row.testCaseList.length
                }}</el-tag>
              </div>
            </div>
            <span v-else>-</span>
          </template>
        </el-table-column>

        <el-table-column label="迭代版本" width="220">
          <template #default="scope">
            <div
              v-if="scope.row && scope.row.testCaseList"
              class="demand-info-cell"
            >
              <div
                v-if="scope.row.testCaseInfo && scope.row.testCaseInfo.version"
                class="info-item"
              >
                <span>{{ scope.row.testCaseInfo.version }}</span>
              </div>
            </div>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="推荐测试人员" width="220">
          <template #default="scope">
            <div
              v-if="scope.row && scope.row.testCaseInfo"
              class="demand-info-cell"
            >
              <div
                v-if="scope.row.testCaseInfo.assignedTester"
                class="info-item"
              >
                <!-- 测试人员名称 -->
                <el-tag size="small" type="success">
                  {{ scope.row.testCaseInfo.assignedTester }}
                </el-tag>

                <!-- 分析测试人员技术栈和等级 -->
                <div class="tester-tags">
                  <!-- 查找对应的测试人员数据 -->
                  <template
                    v-if="
                      getTestCaseTester(scope.row.testCaseInfo.assignedTester)
                    "
                  >
                    <!-- 技术栈：红色 -->
                    <el-tag
                      v-for="(tech, index) in getTestCaseTester(
                        scope.row.testCaseInfo.assignedTester
                      ).technologyStack"
                      :key="'tech-' + index"
                      size="small"
                      type="danger"
                      style="margin: 2px"
                    >
                      {{ tech }}
                    </el-tag>

                    <!-- 能力等级：蓝色 -->
                    <el-tag
                      v-if="
                        getTestCaseTester(scope.row.testCaseInfo.assignedTester)
                          .level
                      "
                      size="small"
                      type="primary"
                      style="margin: 2px"
                    >
                      {{
                        getTestCaseTester(scope.row.testCaseInfo.assignedTester)
                          .level
                      }}
                    </el-tag>
                  </template>
                </div>
              </div>
            </div>
            <span v-else>-</span>
          </template>
        </el-table-column>

        <el-table-column
          prop="createTime"
          label="创建时间"
          width="150"
          sortable
        >
          <template #default="scope">
            {{ formatDate(scope.row.createTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150" fixed="right">
          <template #default="scope">
            <el-button
              type="primary"
              size="small"
              link
              @click="handleEdit(scope.row)"
            >
              管理
            </el-button>
            <el-button
              type="danger"
              size="small"
              link
              @click="handleDelete(scope.row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 使用封装的任务上传组件 -->
    <TaskUpload
      v-model:visible="uploadDialogVisible"
      title="上传需求书"
      :allowedTypes="['doc', 'docx']"
      @upload-success="handleUploadSuccess"
      @upload-cancel="handleUploadCancel"
      :loading="uploadLoading"
    />

    <!-- AI处理响应区域 -->
    <el-card v-if="showResponse" class="form-card response-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <span>AI分析结果</span>
          <el-button type="text" @click="clearResponse">关闭</el-button>
        </div>
      </template>
      <div class="response-content">
        <el-skeleton :rows="6" animated v-if="aiLoading" />
        <div v-else>{{ aiResponse }}</div>
      </div>
    </el-card>

    <!-- 使用封装的任务编辑组件 -->
    <TestCaseEditDialog
      v-model="editDialogVisible"
      :test-case-data="editForm"
      @save="saveEdit"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from "vue";
import {
  Edit,
  Delete,
  Plus,
  Search,
  RefreshRight,
  Download,
  Connection,
} from "@element-plus/icons-vue";
import { ElMessage, ElLoading } from "element-plus";
import TaskUpload from "@/views/TestCase/components/TestCaseUpload.vue";
import TaskDetail from "@/views/TestCase/components/TestCaseDetail.vue";
import TestCaseEditDialog from "@/views/TestCase/components/TestCaseEditDialog.vue";
import { testCase } from "@/utils/cueWords";
import { uploadAttachment } from "@/api/task";
import axios from "axios";

// 搜索表单
const status = ref("全部");
const name = ref("");
const code = ref("");

// 表格数据
const tableData = ref([]);
// 原始数据备份，用于过滤和重置
const originalTableData = ref([]);

// 本地存储键名
const STORAGE_KEY = "test_case_table_data";

// 初始化时从本地存储加载数据
onMounted(() => {
  const storedData = localStorage.getItem(STORAGE_KEY);
  if (storedData) {
    try {
      const parsedData = JSON.parse(storedData);
      tableData.value = parsedData;
      originalTableData.value = parsedData;
    } catch (e) {
      console.error("Failed to parse stored data:", e);
    }
  }
});

// 监听tableData变化，保存到本地存储
watch(
  tableData,
  (newValue) => {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(newValue));
    // 当tableData发生非过滤性质的变化时，同步更新originalTableData
    if (status.value === "全部" && !name.value && !code.value) {
      originalTableData.value = JSON.parse(JSON.stringify(newValue));
    }
  },
  { deep: true }
);

// 查询方法
const handleSearch = () => {
  // 从原始数据中过滤
  tableData.value = originalTableData.value.filter((item) => {
    // 状态过滤（全部状态不过滤）
    const statusMatch =
      status.value === "" ||
      status.value === "全部" ||
      item.status === status.value;

    // 需求名称过滤（模糊匹配）
    const nameMatch =
      !name.value || item.name.toLowerCase().includes(name.value.toLowerCase());

    // 需求编号过滤（模糊匹配）
    const codeMatch =
      !code.value || item.code.toLowerCase().includes(code.value.toLowerCase());

    // 所有条件都满足才返回true
    return statusMatch && nameMatch && codeMatch;
  });

  console.log("查询条件", {
    status: status.value,
    name: name.value,
    code: code.value,
  });
  console.log("过滤后数据条数:", tableData.value.length);
};

// 重置方法
const resetSearch = () => {
  status.value = "全部";
  name.value = "";
  code.value = "";

  // 恢复原始数据
  tableData.value = JSON.parse(JSON.stringify(originalTableData.value));
  console.log("重置搜索，恢复所有数据");
};

// 文件上传相关
const uploadDialogVisible = ref(false);
const uploadLoading = ref(false);
const aiLoading = ref(false);
let loadingInstance = null;

// 打开上传弹窗
const openUploadDialog = () => {
  uploadDialogVisible.value = true;
};

// 添加响应相关的 ref
const aiResponse = ref("");
const showResponse = ref(false);

// 清除响应内容
const clearResponse = () => {
  aiResponse.value = "";
  showResponse.value = false;
};

// 修改处理上传成功的方法 - 使用模拟上传
const handleUploadSuccess = async (file) => {
  uploadLoading.value = true;
  
  // 原来的真实上传代码（已注释，避免OSS费用）
  // const formData = new FormData();
  // formData.append("file", file);
  // uploadAttachment(formData)
  //   .then((response) => {
  //     uploadDialogVisible.value = false; // 上传成功后关闭弹窗
  //     uploadLoading.value = false;
  //     handleChat(response.data.data, file.name);
  //     ElMessage.success("文件上传成功");
  //   })
  //   .catch((error) => {
  //     uploadLoading.value = false;
  //     ElMessage.error("文件上传失败");
  //     console.error("上传失败:", error);
  //   });
  
  // 模拟上传过程，延迟1秒
  setTimeout(() => {
    uploadDialogVisible.value = false; // 上传成功后关闭弹窗
    uploadLoading.value = false;
    
    // 使用模拟的OSS地址
    const mockOssUrl = "https://test-yy.tos-cn-shanghai.volces.com/%E3%80%90%E5%AE%A2%E6%88%B7%E3%80%91%E4%B8%AD%E5%9B%BD%E9%93%81%E5%A1%94_%E9%93%81%E5%A1%94%E8%A7%86%E8%81%94%E5%B9%B3%E5%8F%B0__%E5%B7%A5%E4%BD%9C%E5%8F%B0-%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86-%E7%AE%97%E6%B3%95%E9%85%8D%E7%BD%AE%E4%BC%98%E5%8C%96_%E9%9C%80%E6%B1%82%E8%A7%84%E6%A0%BC%E8%AF%B4%E6%98%8E%E4%B9%A620250409.docx?X-Tos-Algorithm=TOS4-HMAC-SHA256&X-Tos-Credential=AKLTMjdmZDRlZmU4YmQxNDZhZDlhYjkyMmJlYzMwNmFlNjc%2F20250916%2Fcn-shanghai%2Ftos%2Frequest&X-Tos-Expires=3600&X-Tos-Date=20250916T094513Z&X-Tos-Signature=367111f250495f9d59511edd29c150216cdb342dbbe7c858963e2aa12396001a&X-Tos-SignedHeaders=host";
    
    handleChat(mockOssUrl, file.name);
    ElMessage.success("文件上传成功（模拟）");
  }, 1000);
};

// 处理上传取消
const handleUploadCancel = () => {
  console.log("取消上传");
};

const handleChat = async (
  path,
  fileName = "1.7.40__【客户】中国铁塔_铁塔视联平台__告警详情专业版优化_需求规格说明书20250403.docx"
  ) => {
    console.log(path);
  
    // 显示加载状态
  aiLoading.value = true;
  showResponse.value = true;
  aiResponse.value = "";

  // 使用 ElLoading.service 创建全屏加载
  loadingInstance = ElLoading.service({
    fullscreen: true,
    text: "正在处理中...",
    background: "rgba(0, 0, 0, 0.8)",
  });

  const messages1 = [
    {
      role: "system",
      content: testCase,
    },

    {
      role: "user",
      content: `"${path}",
    1. 根据文档标题，找到对应的版本号。
    2. 分析文档，列出这个版本的新增需求。
    3. 匹配最适合的测试人员
    4. 并根据敏捷开发思想, 梳理认识任务, 评价任务难易度, 并给出预计测试时间。

    返回JSON 格式字符串，格式如下：
    {
      "iterativeVersion": "文档控制记录中最大的版本号",
      "newDemands": [
        {
          "demandName": "需求名称",
          "demandDescription": "需求描述",
          "difficulty": "难易度",
          "expectedTime": "预计开发时间",
          "startTime": "开始时间 yyyy-MM-dd",
          "endTime": "结束时间 yyyy-MM-dd",
          "testCaseList": [
            {
              "demandName": "编号",
              "description": "步骤",
              "preconditions": "预期",
            }
          ]
        }
      ],
      "testDeveloper": {
        "name": "测试开发人员姓名",
        "expertise": ["擅长领域1", "擅长领域2"]
      },
    }`,
    },
  ];

  const requestOptions = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "doubao-seed-1-6-250615",
      stream: true,
      messages: messages1,
    }),
    keepalive: true,
  };

  try {
    const response = await fetch(
      "http://127.0.0.1:18889/chat",
      requestOptions
    );

    if (!response.ok) {
      throw new Error(`HTTP 错误：${response.status}`);
    }

    // 读取响应体为可读流
    const stream = response.body;
    if (!stream) {
      throw new Error("响应体为空");
    }

    // 创建文本解码器（处理 UTF-8 编码）
    const decoder = new TextDecoder("utf-8");
    const reader = stream.getReader();

    let buffer = "";

    // eslint-disable-next-line no-constant-condition
    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        break;
      }

      const chunk = decoder.decode(value, { stream: true });
      buffer += chunk; // 合并到缓冲区
    }

    console.log(buffer);
    processBuffer(buffer);
    console.log("流读取完成，开始处理响应");
    aiLoading.value = false;
    let parsedData;
    try {
      // 尝试提取JSON格式的数据，查找第一个{和最后一个}之间的内容
      const jsonMatch = aiResponse.value.match(/\{[\s\S]*\}/);
      if (jsonMatch) {
        parsedData = JSON.parse(jsonMatch[0]);
      } else {
        // 如果没有找到有效的JSON格式，则尝试直接解析
        parsedData = JSON.parse(aiResponse.value);
      }
    } catch (error) {
      console.error("JSON解析失败:", error);
      ElMessage.error("解析AI响应失败，请重试");
      throw new Error("JSON解析失败");
    }
    console.log("解析后的数据:", parsedData);
    addTask(parsedData, fileName);
    ElMessage.success("成功添加需求");
  } catch (error) {
    console.error("获取流数据失败:", error);
    // 可在此处添加重试逻辑
    ElMessage.error("读取响应流失败");
  } finally {
    aiLoading.value = false;
    // 关闭加载遮罩
    if (loadingInstance) {
      loadingInstance.close();
    }
  }
};

function processBuffer(chunk) {
  // 按 \n 分割行，保留最后一个不完整的行（可能以 \r\n 结尾，需兼容）
  const lines = chunk.split("\n");

  lines.forEach((line) => {
    if (line === "" || line == null) return; // 忽略空行（事件结束符）

    // 处理不同格式的数据
    if (line.startsWith("data:")) {
      let content = "";

      // 处理 data:data: 格式
      if (line.startsWith("data:data:")) {
        const data = line.split("data:data:");
        if (data.length > 1 && data[1] !== "[DONE]") {
          content = data[1];
        }
      }
      // 处理 data: 格式
      else {
        const data = line.substring(5); // 去掉 "data:" 前缀
        if (data && data !== "[DONE]") {
          content = data;
        }
      }

      if (content) {
        try {
          const parsed = JSON.parse(content);
          if (parsed.choices && parsed.choices[0]?.delta?.content) {
            aiResponse.value += parsed.choices[0].delta.content;
          }
        } catch (error) {
          console.log("解析失败=====>");
          console.log(lines);
          console.log(content);
          console.log("解析失败<=====");
          console.error("解析失败:", error);
        }
      }
    }
  });
}

function addTask(parsedData, fileName) {
  console.log("添加的需求:", parsedData);

  // 生成需求书编号前缀
  const prefix = `TC${new Date().getFullYear()}`;

  // 创建需求书记录
  if (parsedData && parsedData.newDemands && parsedData.newDemands.length > 0) {
    // 为需求书生成一个唯一的编号
    const demandCode = `${prefix}${String(tableData.value.length + 1).padStart(
      3,
      "0"
    )}`;

    // 创建需求书记录
    const demandRecord = {
      code: demandCode,
      name: fileName,
      status: "已分配",
      createTime: new Date().toISOString().split("T")[0],

      // 基本信息
      testCaseInfo: {
        demandName: fileName.replace(/\.[^/.]+$/, ""), // 去掉文件扩展名
        description: "需求书包含多个测试用例",
        version: parsedData.iterativeVersion || "1.0",
        assignedTester: parsedData.testDeveloper?.name || "",
        priority: "P2",
        type: "功能测试",
      },

      // 需求信息 - 使用空对象确保其存在
      demandInfo: {
        iterativeVersion: parsedData.iterativeVersion || "1.0",
        testDeveloper: parsedData.testDeveloper || { name: "", expertise: [] },
      },

      // 需求中的所有测试用例 - 确保是数组
      testCaseList: [],
    };

    // 处理每个需求
    parsedData.newDemands.forEach((demand, index) => {
      // 确保每个需求的必要属性存在
      const safeDemand = {
        demandName: demand.demandName || `需求${index + 1}`,
        demandDescription: demand.demandDescription || "",
        difficulty: demand.difficulty || "中",
        expectedTime: demand.expectedTime || "",
        startTime: demand.startTime || new Date().toISOString().split("T")[0],
        endTime: demand.endTime || "",
        testCaseList: Array.isArray(demand.testCaseList)
          ? demand.testCaseList
          : [],
      };

      // 收集所有测试用例
      const testCases = [];

      // 如果需求有测试用例列表
      if (safeDemand.testCaseList.length > 0) {
        safeDemand.testCaseList.forEach((testCaseItem, caseIndex) => {
          testCases.push({
            id: `${index + 1}-${caseIndex + 1}`,
            demandName: safeDemand.demandName,
            description: testCaseItem.description || "步骤未提供",
            preconditions: testCaseItem.preconditions || "预期结果未提供",
            difficulty: safeDemand.difficulty,
            expectedTime: safeDemand.expectedTime,
            startTime: safeDemand.startTime,
            endTime: safeDemand.endTime,
          });
        });
      } else {
        // 没有测试用例列表，创建一个默认的测试用例
        testCases.push({
          id: `${index + 1}-1`,
          demandName: safeDemand.demandName,
          description: "测试用例步骤未提供",
          preconditions: "预期结果未提供",
          difficulty: safeDemand.difficulty,
          expectedTime: safeDemand.expectedTime,
          startTime: safeDemand.startTime,
          endTime: safeDemand.endTime,
        });
      }

      // 添加需求信息
      demandRecord.demandInfo[`demand_${index + 1}`] = safeDemand;

      // 将测试用例添加到总列表
      demandRecord.testCaseList = demandRecord.testCaseList.concat(testCases);
    });

    // 添加到表格数据
    tableData.value.push(demandRecord);

    // 更新本地存储
    localStorage.setItem(STORAGE_KEY, JSON.stringify(tableData.value));

    // 提示创建成功
    ElMessage.success(
      `成功创建需求书记录，包含 ${demandRecord.testCaseList.length} 个测试用例`
    );
  }
}

// 编辑相关
const editDialogVisible = ref(false);
const editForm = ref({
  id: "",
  demandId: "",
  demandName: "",
  description: "",
  preconditions: "",
  expectedTime: 1,
  timeRange: [],
  steps: [],
  testCaseInfo: {
    priority: "中",
    assignedTester: "",
    version: "v1.0",
    startTime: "",
    endTime: "",
  },
});

// 编辑方法 - 当点击表格行中的编辑按钮时调用
const handleEdit = (row) => {
  // 复制一份数据用于编辑，避免直接修改原数据
  editForm.value = JSON.parse(JSON.stringify(row));

  console.log("编辑数据:", editForm.value);

  // 打开编辑对话框
  editDialogVisible.value = true;
};

// 从字符串解析测试步骤
const parseStepsFromString = (stepsString) => {
  if (!stepsString || typeof stepsString !== "string") return [];

  const steps = [];
  // 尝试不同的分隔模式
  let stepLines = stepsString.split(/\n\n|\n(?=步骤\d+:)/);

  // 如果没有分割出条目，尝试按段落分割
  if (stepLines.length <= 1) {
    stepLines = stepsString.split(/\n\s*\n|\.\s*\n/);
  }

  for (const stepLine of stepLines) {
    if (stepLine.trim()) {
      const actionMatch = stepLine.match(/步骤\d+:\s*(.*)|操作[:：](.*)/i);
      const expectedMatch = stepLine.match(/预期[:：]\s*(.*)|结果[:：](.*)/i);

      if (actionMatch || expectedMatch) {
        steps.push({
          action: actionMatch
            ? actionMatch[1] || actionMatch[2] || ""
            : stepLine.trim(),
          expected: expectedMatch
            ? expectedMatch[1] || expectedMatch[2] || ""
            : "",
          tester: "",
          environment: "测试环境",
        });
      }
    }
  }

  // 如果没有解析出步骤，但有内容，创建一个默认步骤
  if (steps.length === 0 && stepsString.trim()) {
    steps.push({
      action: stepsString.trim(),
      expected: "需设置预期结果",
      tester: "",
      environment: "测试环境",
    });
  }

  return steps;
};

// 保存编辑
const saveEdit = (updatedData) => {
  console.log("保存数据:", updatedData);

  // 判断是编辑需求任务还是测试用例
  if (updatedData.testCaseList) {
    // 更新整个需求任务
    const index = tableData.value.findIndex(
      (item) => item.code === updatedData.code
    );
    if (index !== -1) {
      // 确保每个测试用例都有正确的assignedTester和testCaseInfo.assignedTester
      if (updatedData.testCaseList && updatedData.testCaseList.length > 0) {
        updatedData.testCaseList.forEach((testCase) => {
          if (!testCase.testCaseInfo) {
            testCase.testCaseInfo = {};
          }

          // 同步测试人员信息
          if (testCase.assignedTester) {
            testCase.testCaseInfo.assignedTester = testCase.assignedTester;
          } else if (testCase.testCaseInfo.assignedTester) {
            testCase.assignedTester = testCase.testCaseInfo.assignedTester;
          } else if (
            updatedData.testCaseInfo &&
            updatedData.testCaseInfo.assignedTester
          ) {
            testCase.assignedTester = updatedData.testCaseInfo.assignedTester;
            testCase.testCaseInfo.assignedTester =
              updatedData.testCaseInfo.assignedTester;
          }
        });
      }

      // 更新需求任务中的demandInfo中的assignedTester
      if (updatedData.demandInfo) {
        for (const key in updatedData.demandInfo) {
          if (key.startsWith("demand_")) {
            const demand = updatedData.demandInfo[key];
            if (
              demand &&
              demand.testCaseList &&
              demand.testCaseList.length > 0
            ) {
              // 如果demand有assignedTester，同步到它的所有testCase
              if (demand.assignedTester) {
                demand.testCaseList.forEach((testCase) => {
                  if (!testCase.assignedTester) {
                    testCase.assignedTester = demand.assignedTester;
                  }
                });
              }
            }
          }
        }
      }

      tableData.value[index] = JSON.parse(JSON.stringify(updatedData));

      // 同步更新originalTableData
      const originalIndex = originalTableData.value.findIndex(
        (item) => item.code === updatedData.code
      );
      if (originalIndex !== -1) {
        originalTableData.value[originalIndex] = JSON.parse(
          JSON.stringify(updatedData)
        );
      }
      ElMessage.success("需求编辑成功");
    } else {
      ElMessage.error("编辑失败：未找到对应需求");
    }
  } else {
    // 更新单个测试用例的逻辑保持不变
    let found = false;
    let parentDemand = null;

    // 遍历所有需求，查找匹配的测试用例
    for (let i = 0; i < tableData.value.length; i++) {
      const demand = tableData.value[i];

      if (demand.testCaseList && Array.isArray(demand.testCaseList)) {
        const testCaseIndex = demand.testCaseList.findIndex(
          (tc) => tc.id === updatedData.id
        );

        if (testCaseIndex !== -1) {
          parentDemand = demand;

          // 检查是否需要转移到其他需求
          if (
            updatedData.demandId &&
            updatedData.demandId !== (demand.code || demand.id)
          ) {
            // 需要转移到不同的需求
            const targetDemand = tableData.value.find(
              (item) => (item.code || item.id) === updatedData.demandId
            );

            if (targetDemand) {
              // 从当前需求中删除
              demand.testCaseList.splice(testCaseIndex, 1);

              // 准备要添加的测试用例数据
              const updatedTestCase = prepareTestCaseData(
                updatedData,
                targetDemand
              );

              // 添加到目标需求
              if (!targetDemand.testCaseList) {
                targetDemand.testCaseList = [];
              }

              targetDemand.testCaseList.push(updatedTestCase);

              // 同步到originalTableData
              updateOriginalTableData();

              ElMessage.success("测试用例已成功转移到其他需求");
              found = true;
              break;
            } else {
              ElMessage.error("转移失败：未找到目标需求");
              return;
            }
          } else {
            // 在当前需求中更新
            const updatedTestCase = prepareTestCaseData(updatedData, demand);

            // 更新测试用例
            demand.testCaseList[testCaseIndex] = updatedTestCase;

            // 同步到original数据
            const originalDemand = originalTableData.value.find(
              (item) => item.code === demand.code
            );

            if (originalDemand && originalDemand.testCaseList) {
              const originalTestCaseIndex =
                originalDemand.testCaseList.findIndex(
                  (tc) => tc.id === updatedData.id
                );

              if (originalTestCaseIndex !== -1) {
                originalDemand.testCaseList[originalTestCaseIndex] = JSON.parse(
                  JSON.stringify(updatedTestCase)
                );
              }
            }

            ElMessage.success("测试用例编辑成功");
            found = true;
            break;
          }
        }
      }
    }

    if (!found) {
      // 若未找到现有测试用例，视为新增测试用例
      if (updatedData.demandId) {
        const targetDemand = tableData.value.find(
          (item) => (item.code || item.id) === updatedData.demandId
        );

        if (targetDemand) {
          if (!targetDemand.testCaseList) {
            targetDemand.testCaseList = [];
          }

          // 准备要添加的测试用例数据
          const newTestCase = prepareTestCaseData(updatedData, targetDemand);

          targetDemand.testCaseList.push(newTestCase);

          // 同步到original数据
          updateOriginalTableData();

          ElMessage.success("测试用例添加成功");
        } else {
          ElMessage.error("添加失败：未找到对应需求");
        }
      } else {
        ElMessage.error("编辑失败：未指定所属需求");
      }
    }
  }

  // 更新本地存储
  localStorage.setItem(STORAGE_KEY, JSON.stringify(tableData.value));
};

// 准备测试用例数据，确保所有必要字段都存在
const prepareTestCaseData = (testCaseData, parentDemand) => {
  const result = JSON.parse(JSON.stringify(testCaseData));

  // 确保有测试用例基本信息
  if (!result.testCaseInfo) {
    result.testCaseInfo = {};
  }

  // 处理基本字段
  result.difficulty = result.testCaseInfo.priority || result.difficulty || "中";
  result.assignedTester =
    result.testCaseInfo.assignedTester || result.assignedTester || "";

  // 处理时间字段
  if (result.timeRange && result.timeRange.length === 2) {
    result.startTime = result.timeRange[0];
    result.endTime = result.timeRange[1];
    result.testCaseInfo.startTime = result.timeRange[0];
    result.testCaseInfo.endTime = result.timeRange[1];
  }

  // 确保有需求名称
  if (!result.demandName) {
    result.demandName =
      parentDemand.name ||
      parentDemand.testCaseInfo?.demandName ||
      "未命名需求";
  }

  // 确保版本信息
  if (!result.testCaseInfo.version) {
    result.testCaseInfo.version =
      parentDemand.testCaseInfo?.version ||
      parentDemand.demandInfo?.iterativeVersion ||
      "v1.0";
  }

  return result;
};

// 更新originalTableData，保持与tableData同步
const updateOriginalTableData = () => {
  if (status.value === "全部" && !name.value && !code.value) {
    originalTableData.value = JSON.parse(JSON.stringify(tableData.value));
  }
};

// 删除方法
const handleDelete = (row) => {
  const index = tableData.value.findIndex((item) => item.code === row.code);
  if (index !== -1) {
    tableData.value.splice(index, 1);
    const originalIndex = originalTableData.value.findIndex(
      (item) => item.code === row.code
    );
    if (originalIndex !== -1) {
      originalTableData.value.splice(originalIndex, 1);
    }
    ElMessage.success("删除成功");
  } else {
    ElMessage.error("删除失败：未找到对应数据");
  }
};

// 表格选择相关
const multipleSelection = ref([]);
const handleSelectionChange = (selection) => {
  multipleSelection.value = selection;
  console.log("当前选中的行:", multipleSelection.value);
};

// 批量操作方法
const handleBatchAction = async () => {
  if (multipleSelection.value.length === 0) {
    ElMessage.warning("请至少选择一条记录");
    return;
  }

  // 创建加载实例
  const loadingInstance = ElLoading.service({
    fullscreen: true,
    text: "正在推送到禅道...",
    background: "rgba(0, 0, 0, 0.7)",
  });

  try {
    let successCount = 0;
    let failedCount = 0;
    const allTestCases = [];
    const invalidTasks = [];

    // 收集所有需要处理的测试用例
    multipleSelection.value.forEach((item) => {
      // 检查测试用例列表
      if (item.testCaseList && item.testCaseList.length > 0) {
        // 收集需求中所有任务的测试人员
        const demandAssignedTesters = {};
        if (item.demandInfo) {
          for (const key in item.demandInfo) {
            if (key.startsWith("demand_")) {
              const demand = item.demandInfo[key];
              if (demand.assignedTester) {
                demandAssignedTesters[demand.demandName] =
                  demand.assignedTester;
              }
            }
          }
        }

        // 检查每个测试用例是否有测试人员
        item.testCaseList.forEach((testCase) => {
          // 优先使用测试用例自己的assignedTester，然后使用对应demand的assignedTester，最后使用全局的
          const assignedTester =
            testCase.assignedTester ||
            demandAssignedTesters[testCase.demandName] ||
            (testCase.testCaseInfo
              ? testCase.testCaseInfo.assignedTester
              : null) ||
            item.testCaseInfo?.assignedTester;

          if (assignedTester) {
            // 构造步骤数据
            let step = null;
            if (testCase.description) {
              // 如果description字段看起来像是多个步骤，尝试解析它
              const stepsFromDesc = parseStepsFromString(testCase.description);
              if (stepsFromDesc.length > 0) {
                step = {
                  desc: stepsFromDesc[0].action || testCase.description,
                  expect:
                    stepsFromDesc[0].expected || testCase.preconditions || "",
                };
              } else {
                // 如果没有解析出步骤，使用整个description作为一个步骤
                step = {
                  desc: testCase.description,
                  expect: testCase.preconditions || "",
                };
              }
            } else {
              // 如果没有步骤描述，创建一个空步骤
              step = {
                desc: "测试步骤未提供",
                expect: testCase.preconditions || "预期结果未提供",
              };
            }

            // 将测试用例添加到需要处理的列表中
            allTestCases.push({
              testCase: testCase,
              title: testCase.demandName || item.name,
              assignedTo: assignedTester,
              step: step,
              parentItem: item,
            });
          } else {
            // 记录没有测试人员的用例
            invalidTasks.push(testCase.demandName || "未命名测试用例");
          }
        });
      } else {
        // 如果没有测试用例列表，且有全局的测试人员，也可以推送整个需求
        if (item.testCaseInfo?.assignedTester) {
          const step = {
            desc: item.testCaseInfo.description || "测试步骤未提供",
            expect: "预期结果未提供",
          };

          allTestCases.push({
            testCase: item,
            title: item.name,
            assignedTo: item.testCaseInfo.assignedTester,
            step: step,
            parentItem: item,
          });
        } else {
          invalidTasks.push(item.name || "未命名测试用例");
        }
      }
    });

    // 如果有无效任务，提示并终止操作
    if (invalidTasks.length > 0) {
      loadingInstance.close();
      ElMessage.error(
        `以下测试用例未分配测试人员，请先分配：${invalidTasks.join(", ")}`
      );
      return;
    }

    // 按title分组，合并相同title的测试用例步骤
    const groupedByTitle = {};
    allTestCases.forEach((testCaseItem) => {
      const title = testCaseItem.title;
      if (!groupedByTitle[title]) {
        groupedByTitle[title] = {
          title: title,
          steps: [],
          assignedTo: testCaseItem.assignedTo,
          testCases: [],
          parentItems: new Set(),
        };
      }

      // 添加步骤到对应title的组中
      groupedByTitle[title].steps.push(testCaseItem.step);

      // 记录原始测试用例，用于后续状态更新
      groupedByTitle[title].testCases.push(testCaseItem.testCase);

      // 记录父项，用于更新状态
      groupedByTitle[title].parentItems.add(testCaseItem.parentItem);
    });

    // 将分组转为数组，用于发送请求
    const tasksToSend = Object.values(groupedByTitle);

    console.log("按title分组后准备推送的测试用例:", tasksToSend);

    // 转换测试人员名称为禅道用户名
    const getZentaoUsername = (testerName) => {
      // 如果测试人员名称为空，返回空数组
      if (!testerName) return [];

      const nameMapping = {
        // 前端和后端开发人员（可能会在测试时使用）
        王文权: "wangwenquan",
        慈兆彤: "cizhaotong",
        杨宽: "yangkuan",
        张瑞: "zhangrui",
        易瑶: "yiyao",
        胡恩德: "huende",
        刘政铁: "liuzhengtie",
        // 测试人员（来自testCase字段）
        崔艳: "cuiyan",
        李元奇: "liyuanqi",
      };
      return [nameMapping[testerName] || ""]; // 如果找不到映射，返回空字符串
    };

    // 使用 Promise.all 并行处理所有请求
    const results = await Promise.allSettled(
      tasksToSend.map(async (task) => {
        try {
          // 获取测试人员的禅道用户名
          const assignedToArray = getZentaoUsername(task.assignedTo);

          // 如果没有分配测试人员，跳过此任务
          if (!assignedToArray.length || !assignedToArray[0]) {
            console.warn(`测试用例 ${task.title} 没有有效的测试人员，跳过推送`);
            return {
              success: false,
              task: task.title,
              error: "没有有效的测试人员",
            };
          }

          // 构建请求参数
          const requestData = {
            product: "1", // 写死，1是视联通用
            pri: 1,
            type: "feature", // 写死
            title: task.title,
            steps: task.steps,
            assignedTo: assignedToArray, // 添加分配给谁
          };

          console.log("推送测试用例:", requestData);

          // 调用禅道接口
          const response = await axios.post(
            "http://127.0.0.1:18889/zentao/testcases/create",
            requestData
          );

          // 更新测试用例状态
          task.testCases.forEach((testCase) => {
            testCase.status = "已推送";
          });

          return { success: true, task: task.title };
        } catch (error) {
          console.error("推送失败:", task.title, error);
          return { success: false, task: task.title, error };
        }
      })
    );

    // 更新所选测试用例的状态
    multipleSelection.value.forEach((item) => {
      item.status = "已推送";
    });

    // 更新本地存储
    localStorage.setItem(STORAGE_KEY, JSON.stringify(tableData.value));

    // 统计成功和失败数量
    results.forEach((result) => {
      if (result.status === "fulfilled" && result.value.success) {
        successCount++;
      } else {
        failedCount++;
      }
    });

    // 显示结果
    if (successCount > 0 && failedCount === 0) {
      ElMessage.success(`成功推送 ${successCount} 个测试用例到禅道`);
    } else if (successCount > 0 && failedCount > 0) {
      ElMessage.warning(
        `推送结果: ${successCount} 个成功, ${failedCount} 个失败`
      );
    } else {
      ElMessage.error(`推送失败: ${failedCount} 个测试用例未能成功推送`);
    }
  } catch (error) {
    console.error("批量操作异常:", error);
    ElMessage.error("推送过程中发生错误");
  } finally {
    loadingInstance.close();
  }
};

// 格式化日期为yyyy-MM-dd
const formatDate = (dateString) => {
  if (!dateString) return "";

  try {
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return dateString; // 如果无法解析为日期，返回原字符串

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");

    return `${year}-${month}-${day}`;
  } catch (error) {
    console.error("日期格式化错误:", error);
    return dateString;
  }
};

// 从testCase数据中获取测试人员信息
const getTestCaseTester = (testerName) => {
  try {
    // 解析testCase字符串为JSON对象
    const testCaseData = JSON.parse(testCase);
    if (testCaseData && testCaseData.developers) {
      // 查找匹配的测试人员
      const tester = testCaseData.developers.find(
        (dev) => dev.name === testerName
      );
      if (tester) {
        return {
          name: tester.name,
          expertise: tester.skills || [],
          technologyStack: tester.technologyStack || [],
          level: tester.level || "",
        };
      }
    }
  } catch (error) {
    console.error("解析测试人员数据失败:", error);
  }

  // 如果找不到或解析失败，返回基本信息
  return {
    name: testerName,
    expertise: [],
    technologyStack: [],
    level: "",
  };
};
</script>

<style scoped lang="scss">
.task-container {
  padding: 16px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 64px);

  .form-card {
    margin-bottom: 16px;
    background-color: #fff;

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
      font-size: 16px;
    }
    .search-row {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 16px;

      .search-item {
        display: flex;
        align-items: center;
        margin-bottom: 10px;

        .label {
          margin-right: 8px;
          color: #606266;
          font-size: 14px;
        }

        .input-width {
          width: 200px;
        }
      }

      .buttons {
        margin-left: auto;
        display: flex;
        gap: 8px;
      }
    }
  }

  .task-list-card {
    .left-actions {
      display: flex;
      align-items: center;
    }

    .right-actions {
      display: flex;
      gap: 8px;
    }

    .add-task-btn,
    .add-test-case-btn,
    .action-btn {
      display: flex;
      align-items: center;
      gap: 4px;
    }

    .divider {
      height: 1px;
      background-color: #e0e0e0;
      margin: 0 0 16px 0;
      width: 100%;
    }

    .task-table {
      margin-top: 8px;
      border-radius: 4px;
      overflow: hidden;
    }

    .demand-info-cell {
      display: flex;
      flex-direction: column;
      gap: 4px;

      .info-item {
        display: flex;
        align-items: center;
        gap: 4px;

        .label {
          color: #909399;
          font-size: 12px;
        }

        .ellipsis {
          max-width: 140px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          display: inline-block;
        }
      }
    }

    .operation-buttons {
      display: flex;
      justify-content: center;
    }
  }

  .response-card {
    margin-top: 16px;

    .response-content {
      padding: 16px;
      background-color: #f8f8f8;
      border-radius: 4px;
      min-height: 100px;
      max-height: 500px;
      overflow-y: auto;
      white-space: pre-wrap;
      line-height: 1.6;
      font-size: 14px;
      word-break: break-all;
    }
  }

  :deep(.el-table) {
    --el-table-header-bg-color: #f5f7fa;
    --el-table-row-hover-bg-color: #f0f7ff;

    th {
      font-weight: 600;
    }
  }

  :deep(.el-table__expanded-cell) {
    padding: 20px !important;
    background-color: #f8f8f8;
  }
}

// 动画效果
.list-enter-active,
.list-leave-active {
  transition: all 0.3s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}
</style>
